package org.example.java.util.concurrency.lock;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Data {
  private List<String> names;

  ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

  public Data() {
    names = new ArrayList<String>();
  }

  public List<String> getNames() {
    return names;
  }

  public void setNames(List<String> names) {
    this.names = names;
  }

  public void add(String str) {
    lock.writeLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + " Writer: Number of threads waiting : "
          + lock.getQueueLength());

      // This will always be 1.
      System.out.println(Thread.currentThread().getName() + " Writer: Number of write locks waiting : "
          + lock.getWriteHoldCount());
      names.add(str);
      System.out.println(Thread.currentThread().getName() + " Writer: Number of write name : "
          + str);
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    } finally {
      lock.writeLock().unlock();
    }
  }

  public void readData() {
    lock.readLock().lock();
    try {
      System.out.println(Thread.currentThread().getName() + " Reader: Number of threads waiting : "
          + lock.getQueueLength());
      System.out.println(Thread.currentThread().getName() + " Reader: Number of read locks : "
          + lock.getReadLockCount());
      Iterator<String> iter = names.iterator();
      System.out.println(Thread.currentThread().getName() + " read begin: " );
      while (iter.hasNext()) {
//        iter.next();
        System.out.println(Thread.currentThread().getName() + " " + iter.next());
      }
      System.out.println(Thread.currentThread().getName() + " read end. " );
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    } finally {
      lock.readLock().unlock();
    }
  }
}
